package cn.iocoder.yudao.module.happycore.service.oxproject;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.happycore.constants.DirectoryType;
import cn.iocoder.yudao.module.happycore.controller.admin.oxproject.vo.OxProjectPageReqVO;
import cn.iocoder.yudao.module.happycore.controller.admin.oxproject.vo.OxProjectSaveReqVO;
import cn.iocoder.yudao.module.happycore.controller.admin.oxproject.vo.TrainResponse;
import cn.iocoder.yudao.module.happycore.dal.dataobject.oxdirectory.OxDirectoryDO;
import cn.iocoder.yudao.module.happycore.dal.dataobject.oxmodel.OxModelDO;
import cn.iocoder.yudao.module.happycore.dal.dataobject.oxproject.OxProjectDO;
import cn.iocoder.yudao.module.happycore.dal.mysql.oxdirectory.OxDirectoryMapper;
import cn.iocoder.yudao.module.happycore.dal.mysql.oxmodel.OxModelMapper;
import cn.iocoder.yudao.module.happycore.dal.mysql.oxproject.OxProjectMapper;
import cn.iocoder.yudao.module.happycore.service.ProjectFileService;
import cn.iocoder.yudao.module.happycore.service.PythonTrainService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;



import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.happycore.constants.ErrorCodeConstants.*;


/**
 * 项目 Service 实现类
 *
 * @author 昂热
 */
@Service
@Validated
public class OxProjectServiceImpl implements OxProjectService {

    @Resource
    private OxProjectMapper oxProjectMapper;
    @Resource
    private ProjectFileService projectFileService;
    @Resource
    private OxDirectoryMapper oxDirectoryMapper;
    @Resource
    private PythonTrainService pythonTrainService;
    @Resource
    private OxModelMapper oxModelMapper;

    @Override
    @Transactional
    public Long createOxProject(OxProjectSaveReqVO createReqVO) {
        OxProjectDO oxProjectDO = oxProjectMapper.selectOne(Wrappers.<OxProjectDO>lambdaQuery().eq(OxProjectDO::getProjectName, createReqVO.getProjectName()));
        if (ObjectUtils.isNotAllEmpty(oxProjectDO)){
            throw exception(OX_PROJECT_IS_EXISTS);
        }
        String fileInPath = projectFileService.createFileInPath(createReqVO.getProjectName());

        createReqVO.setProjectPath(fileInPath);
        // 插入
        OxProjectDO oxProject = BeanUtils.toBean(createReqVO, OxProjectDO.class);
        //创建训练目录和测试目录
        projectFileService.createTestAndTrain(fileInPath);

        oxProjectMapper.insert(oxProject);
        //创建子目录
        if (!CollectionUtil.isEmpty(createReqVO.getCategoryList())){
            for (String categoryName : createReqVO.getCategoryList()) {
                String subDirectory = projectFileService.createSubDirectory(oxProject.getProjectPath(), categoryName, DirectoryType.test);
                OxDirectoryDO test = new OxDirectoryDO();
                test.setDirectoryName(categoryName);
                test.setProjectId(oxProject.getId());
                test.setType(DirectoryType.test);
                test.setImagesNum(0);
                oxDirectoryMapper.insert(test);

                String trainPath = projectFileService.createSubDirectory(oxProject.getProjectPath(), categoryName, DirectoryType.train);
                OxDirectoryDO train = new OxDirectoryDO();
                train.setDirectoryName(categoryName);
                train.setProjectId(oxProject.getId());
                train.setType(DirectoryType.train);
                train.setImagesNum(0);
                oxDirectoryMapper.insert(train);
            }
        }

        // 返回
        return oxProject.getId();
    }

    @Override
    public void updateOxProject(OxProjectSaveReqVO updateReqVO) {
        // 校验存在
        validateOxProjectExists(updateReqVO.getId());
        // 更新
        OxProjectDO updateObj = BeanUtils.toBean(updateReqVO, OxProjectDO.class);
        oxProjectMapper.updateById(updateObj);
    }

    @Override
    public void deleteOxProject(Long id) {
        // 校验存在
        validateOxProjectExists(id);
        OxProjectDO oxProjectDO = oxProjectMapper.selectById(id);
        projectFileService.deleteProject(oxProjectDO.getProjectPath());
        // 删除
        oxProjectMapper.deleteById(id);
    }

    @Override
        public void deleteOxProjectListByIds(List<Long> ids) {
        // 删除
        oxProjectMapper.deleteByIds(ids);
        }


    private void validateOxProjectExists(Long id) {
        if (oxProjectMapper.selectById(id) == null) {
            throw exception(OX_PROJECT_NOT_EXISTS);
        }
    }

    @Override
    public OxProjectDO getOxProject(Long id) {
        return oxProjectMapper.selectById(id);
    }

    @Override
    public PageResult<OxProjectDO> getOxProjectPage(OxProjectPageReqVO pageReqVO) {
        return oxProjectMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional
    public void addType(Long projectId, String name) {
        validateOxProjectExists(projectId);
        //更新项目分类
        OxProjectDO oxProjectDO = oxProjectMapper.selectById(projectId);
        List<String> categoryList = oxProjectDO.getCategoryList();
        categoryList.add(name);
        oxProjectMapper.updateById(oxProjectDO);
        //test添加目录
        OxDirectoryDO test = new OxDirectoryDO();
        test.setImagesNum(0);
        test.setDirectoryName(name);
        test.setProjectId(projectId);
        test.setType(DirectoryType.test);
        oxDirectoryMapper.insert(test);
        //添加文件夹
        projectFileService.createSubDirectory(oxProjectDO.getProjectPath(),name,DirectoryType.test);

        //train添加目录
        OxDirectoryDO train = new OxDirectoryDO();
        train.setImagesNum(0);
        train.setDirectoryName(name);
        train.setProjectId(projectId);
        train.setType(DirectoryType.train);
        oxDirectoryMapper.insert(train);
        //添加文件夹
        projectFileService.createSubDirectory(oxProjectDO.getProjectPath(),name,DirectoryType.train);
    }

    @Override
    public String getDirectoryPath(Long id) {

        OxDirectoryDO oxDirectoryDO = oxDirectoryMapper.selectById(id);
        if (ObjectUtil.isEmpty(oxDirectoryDO)){
            throw exception(OX_DIRECTORY_NOT_EXISTS);
        }
        OxProjectDO oxProjectDO = oxProjectMapper.selectById(oxDirectoryDO.getProjectId());
        return oxProjectDO.getProjectPath()+DirectoryType.getPath(oxDirectoryDO.getType())+"/"+oxDirectoryDO.getDirectoryName();
    }

    @Override
    public void trainModel(Long projectId) {
        OxProjectDO oxProjectDO = oxProjectMapper.selectById(projectId);
        String projectPath = oxProjectDO.getProjectPath();
        String trainPath = projectPath + "/train";;
        String testPath = projectPath + "/test";
        OxModelDO oxModelDO = new OxModelDO();
        oxModelDO.setProjectId(projectId);
        oxModelMapper.insert(oxModelDO);

        TrainResponse trainResponse = pythonTrainService.trainDogBreedModel(trainPath, testPath, oxModelDO.getId());

    }

}